"""Markdown构建器模块"""

from typing import List, Dict, Any
from contextlib import contextmanager
import io

class MarkdownBuilder:
    """Markdown内容构建器，提供流式API构建Markdown文档"""
    
    def __init__(self, use_section_numbers: bool = False):
        self._content = io.StringIO()
        self._current_indent = 0
        self._use_section_numbers = use_section_numbers
        # 章节编号追踪
        self._section_numbers = [0, 0, 0, 0, 0, 0]  # 最多6级标题
    
    def __str__(self) -> str:
        """获取完整的Markdown文本内容"""
        return self._content.getvalue()
    
    def text(self, content: str) -> 'MarkdownBuilder':
        """添加普通文本"""
        self._content.write(content)
        return self
    
    def line(self, content: str = "") -> 'MarkdownBuilder':
        """添加一行文本，并自动添加换行"""
        self._content.write(content + "\n")
        return self
    
    def newline(self, count: int = 1) -> 'MarkdownBuilder':
        """添加空行"""
        self._content.write("\n" * count)
        return self
    
    def header(self, text: str, level: int = 1) -> 'MarkdownBuilder':
        """
        添加标题
        
        Args:
            text: 标题文本
            level: 标题级别(1-6)
        """
        level = max(1, min(6, level))  # 确保级别在1-6之间
        
        # 更新章节编号
        if self._use_section_numbers and level > 1:  # 只有二级标题及以下才添加编号
            # 递增当前级别的计数器
            self._section_numbers[level-1] += 1
            
            # 重置更低级别的所有计数器
            for i in range(level, 6):
                self._section_numbers[i] = 0
            
            # 生成章节编号字符串
            section_numbers = [num for i, num in enumerate(self._section_numbers) if i < level and num > 0]
            section_number = ".".join(map(str, section_numbers))
            
            # 写入带编号的标题
            numbered_text = f"{section_number}. {text}"
            self._content.write(f"{'#' * level} {numbered_text}\n\n")
            return self
        
        # 写入不带编号的标题
        self._content.write(f"{'#' * level} {text}\n\n")
        return self
    
    def paragraph(self, text: str) -> 'MarkdownBuilder':
        """添加段落"""
        self._content.write(text + "\n\n")
        return self
    
    def bold(self, text: str) -> 'MarkdownBuilder':
        """添加粗体文本"""
        self._content.write(f"**{text}**")
        return self
    
    def italic(self, text: str) -> 'MarkdownBuilder':
        """添加斜体文本"""
        self._content.write(f"*{text}*")
        return self
    
    def code(self, text: str) -> 'MarkdownBuilder':
        """添加行内代码"""
        self._content.write(f"`{text}`")
        return self
    
    def link(self, text: str, url: str) -> 'MarkdownBuilder':
        """添加链接"""
        self._content.write(f"[{text}]({url})")
        return self
    
    def image(self, alt_text: str, url: str, title: str = "") -> 'MarkdownBuilder':
        """添加图片"""
        if title:
            self._content.write(f"![{alt_text}]({url} \"{title}\")")
        else:
            self._content.write(f"![{alt_text}]({url})")
        return self
    
    @contextmanager
    def code_block(self, language: str = ""):
        """代码块上下文管理器"""
        self._content.write(f"```{language}\n")
        yield
        self._content.write("```\n\n")
    
    @contextmanager
    def mermaid(self):
        """Mermaid图表上下文管理器"""
        self._content.write("```mermaid\n")
        yield
        self._content.write("```\n\n")
    
    def horizontal_rule(self) -> 'MarkdownBuilder':
        """添加水平分割线"""
        self._content.write("---\n\n")
        return self
    
    def blockquote(self, text: str) -> 'MarkdownBuilder':
        """添加引用块"""
        lines = text.split("\n")
        for line in lines:
            self._content.write(f"> {line}\n")
        self._content.write("\n")
        return self
    
    def table(self, headers: List[str], rows: List[List[str]]) -> 'MarkdownBuilder':
        """
        添加表格
        
        Args:
            headers: 表头列表
            rows: 表格数据行列表
        """
        # 写入表头
        self._content.write("| " + " | ".join(headers) + " |\n")
        
        # 写入分隔行
        self._content.write("| " + " | ".join(["---"] * len(headers)) + " |\n")
        
        # 写入数据行
        for row in rows:
            # 确保每行的列数与表头相同
            while len(row) < len(headers):
                row.append("")
            
            # 转义表格中的竖线符号
            escaped_row = [str(cell).replace("|", "\\|") for cell in row]
            
            self._content.write("| " + " | ".join(escaped_row) + " |\n")
        
        self._content.write("\n")
        return self
    
    def dict_table(self, data: Dict[str, Any], headers: List[str] = None) -> 'MarkdownBuilder':
        """
        将字典转换为两列表格(键-值)
        
        Args:
            data: 要转换的字典
            headers: 表头，默认为['键', '值']
        """
        if headers is None:
            headers = ['键', '值']
        
        rows = []
        for key, value in data.items():
            # 处理复杂类型的值
            if isinstance(value, (dict, list)):
                import json
                value_str = f"```json\n{json.dumps(value, ensure_ascii=False, indent=2)}\n```"
            elif value is None:
                value_str = "-"
            else:
                value_str = str(value).replace("\n", "<br>")
            
            rows.append([str(key), value_str])
        
        return self.table(headers, rows)
    
    @contextmanager
    def list(self, ordered: bool = False, start: int = 1):
        """
        列表上下文管理器
        
        Args:
            ordered: 是否为有序列表
            start: 有序列表起始编号
        """
        list_builder = _ListBuilder(self._content, ordered, start)
        yield list_builder
        self._content.write("\n")
    
    def definition_list(self, items: Dict[str, str]) -> 'MarkdownBuilder':
        """
        添加定义列表
        
        Args:
            items: 定义项字典，键为术语，值为定义
        """
        for term, definition in items.items():
            self._content.write(f"**{term}**\n: {definition}\n\n")
        return self
    
    def toc(self, headers: List[str]) -> 'MarkdownBuilder':
        """
        添加目录
        
        Args:
            headers: 目录项列表
        """
        # 保存当前章节编号状态
        original_section_numbers = self._section_numbers.copy()
        
        # 重置章节编号计数器(仅用于生成目录)
        temp_section_numbers = [0, 0, 0, 0, 0, 0]
        
        # 写入目录标题
        self._content.write("## 目录\n\n")
        
        if self._use_section_numbers:
            for header in headers:
                # 假设所有headers是二级标题
                temp_section_numbers[1] += 1
                section_number = str(temp_section_numbers[1])
                
                # 为标题添加编号
                numbered_header = f"{section_number}. {header}"
                
                # 创建链接锚点 - 需要匹配实际标题的自动生成的ID
                # 大多数Markdown实现会自动将标题文本转为ID
                # 需要包含章节编号，因为它是标题文本的一部分
                anchor = numbered_header.lower().replace(" ", "-").replace(".", "")
                
                # 写入带编号的目录项
                self._content.write(f"- [{numbered_header}](#{anchor})\n")
        else:
            for header in headers:
                anchor = header.lower().replace(" ", "-")
                self._content.write(f"- [{header}](#{anchor})\n")
        
        # 恢复原始章节编号状态
        self._section_numbers = original_section_numbers
        
        self._content.write("\n")
        return self
    
    def enable_section_numbers(self) -> 'MarkdownBuilder':
        """启用章节编号"""
        self._use_section_numbers = True
        return self
    
    def disable_section_numbers(self) -> 'MarkdownBuilder':
        """禁用章节编号"""
        self._use_section_numbers = False
        return self
    
    def reset_section_numbers(self) -> 'MarkdownBuilder':
        """重置章节编号"""
        self._section_numbers = [0, 0, 0, 0, 0, 0]
        return self


class _ListBuilder:
    """列表构建器，用于构建嵌套列表"""
    
    def __init__(self, content: io.StringIO, ordered: bool = False, start: int = 1):
        self._content = content
        self._ordered = ordered
        self._current_index = start
    
    def item(self, text: str) -> '_ListBuilder':
        """添加列表项"""
        prefix = f"{self._current_index}. " if self._ordered else "- "
        self._content.write(prefix + text + "\n")
        
        if self._ordered:
            self._current_index += 1
            
        return self